package org.openFreely.utils;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.Scanner;
import java.util.concurrent.*;

public class ClientUtils {

    private static String messageInfo;

    private static int messageType;

    private static String message;

    private static String ip;
    private static int port;
    private static int threadCount;
    private static ChannelInitializer channelInitializer;

    public static void bootstrapClient() throws InterruptedException {
        NioEventLoopGroup group=new NioEventLoopGroup(threadCount);
        ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(1,3,60,
                TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        try {
            if (channelInitializer == null) {
                Channel channel = new Bootstrap().group(group)
                        .channel(NioSocketChannel.class)
                        .handler(new ChannelInitializer<Channel>() {
                            @Override
                            protected void initChannel(Channel channel) throws Exception {
                                channel.pipeline().addLast(new StringEncoder());
                            }
                        })
                        .connect(ip, port)
                        .sync().channel();
                threadPoolExecutor.execute(() -> {
                    if (messageType == 1) {
                        channel.writeAndFlush(message);
                    } else {
                        while (true) {
                            Scanner sc = new Scanner(System.in);
                            System.out.println(messageInfo);
                            String message = sc.nextLine();
                            channel.writeAndFlush(message);
                        }
                    }
                });
            } else {
                Channel channel = new Bootstrap().group(new NioEventLoopGroup(threadCount))
                        .channel(NioSocketChannel.class)
                        .handler(channelInitializer)
                        .connect(ip, port)
                        .sync().channel();

                threadPoolExecutor.execute(() -> {
                    if (messageType == 1) {
                        channel.writeAndFlush(message);
                    } else {
                        while (true) {
                            Scanner sc = new Scanner(System.in);
                            System.out.println(messageInfo);
                            String message = sc.nextLine();
                            channel.writeAndFlush(message);
                        }
                    }
                });
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            group.shutdownGracefully();
        }
    }

    public static String getMessageInfo() {
        return messageInfo;
    }

    public static void setMessageInfo(String messageInfo) {
        ClientUtils.messageInfo = messageInfo;
    }

    public static int getMessageType() {
        return messageType;
    }

    public static void setMessageType(int messageType) {
        ClientUtils.messageType = messageType;
    }

    public static String getMessage() {
        return message;
    }

    public static void setMessage(String message) {
        ClientUtils.message = message;
    }

    public static String getIp() {
        return ip;
    }

    public static void setIp(String ip) {
        ClientUtils.ip = ip;
    }

    public static int getPort() {
        return port;
    }

    public static void setPort(int port) {
        ClientUtils.port = port;
    }

    public static int getThreadCount() {
        return threadCount;
    }

    public static void setThreadCount(int threadCount) {
        ClientUtils.threadCount = threadCount;
    }

    public static ChannelInitializer getChannelInitializer() {
        return channelInitializer;
    }

    public static void setChannelInitializer(ChannelInitializer channelInitializer) {
        ClientUtils.channelInitializer = channelInitializer;
    }
}
